/******************************************************************************

    Simple Authentication and Authorisation System (SAAS)

    saas-build.h

    Copyright (C) 2011  Josh Goes


    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    If you require a mailing address for this software, please send your
    mail to the following address:
        SAAS
        GPO Box 2973
        BRISBANE QLD 4001
        AUSTRALIA

******************************************************************************/


#ifndef __H_a7dffdc5ac25a1a4ef41fecd853c6003_
#define __H_a7dffdc5ac25a1a4ef41fecd853c6003_

#include <openssl/sha.h>
#include <openssl/aes.h>
#include <stdint.h>
#include <sys/syslog.h>

#include "saas.h"


///////////////////////////////////////////////////////////////////////////////////////////////
//
//  CONSTANTS
//

// magic IDs
#define SAAS_MAGIC_REQ                                              0x29C20FC1
#define SAAS_MAGIC_RESP                                             0xF3D2039A

// packet types
#define SAAS_PKT_TYPE_PING                                          0x0000
#define SAAS_PKT_TYPE_AUTHENTICATE                                  0x0001
#define SAAS_PKT_TYPE_AUTHORISE                                     0x0002
#define SAAS_PKT_TYPE_CHANGE_PASSWORD                               0x0003
#define SAAS_PKT_TYPE_UID_TO_USERNAME                               0x0004
#define SAAS_PKT_TYPE_USERNAME_TO_UID                               0x0005
#define SAAS_PKT_TYPE_GID_TO_GROUPNAME                              0x0006
#define SAAS_PKT_TYPE_GROUPNAME_TO_GID                              0x0007
#define SAAS_PKT_TYPE_USER_INFO_BY_UID                              0x0008
#define SAAS_PKT_TYPE_USER_INFO_BY_USERNAME                         0x0009
#define SAAS_PKT_TYPE_USER_INFO_WITH_GROUPS_BY_UID                  0x000A
#define SAAS_PKT_TYPE_USER_INFO_WITH_GROUPS_BY_USERNAME             0x000B
#define SAAS_PKT_TYPE_USER_INFO_WITH_ALL_GROUPS_BY_UID              0x000C
#define SAAS_PKT_TYPE_USER_INFO_WITH_ALL_GROUPS_BY_USERNAME         0x000D
#define SAAS_PKT_TYPE_GROUP_INFO_BY_GID                             0x000E
#define SAAS_PKT_TYPE_GROUP_INFO_BY_GROUPNAME                       0x000F
#define SAAS_PKT_TYPE_GROUP_INFO_WITH_MEMBERS_BY_GID                0x0010
#define SAAS_PKT_TYPE_GROUP_INFO_WITH_MEMBERS_BY_GROUPNAME          0x0011
#define SAAS_PKT_TYPE_GROUP_INFO_WITH_ALL_MEMBERS_BY_GID            0x0012
#define SAAS_PKT_TYPE_GROUP_INFO_WITH_ALL_MEMBERS_BY_GROUPNAME      0x0013


// definitions for the host-order config option
#define SAAS_HOST_ORDER_SEQ                                         0x00
#define SAAS_HOST_ORDER_RANDOM                                      0x01


// compiler option
#define __PACKED                                                    __attribute__((__packed__))


// the structure of packet headers (reqs & resps)
typedef struct __PACKED st_pkt_hdr
{
	// a sha256 hash of the whole packet
	uint8_t   hash[32];

	// constant. will be either SAAS_MAGIC_REQ or SAAS_MAGIC_RESP
	uint32_t  magic_id;

	// transaction ID. random number generated for each request/response combo
	uint32_t  trans_id;

	// request/response type
	uint16_t  type;

	// the length of the payload (i.e. data after the packet header)
	uint16_t  payload_len;

	// reserved
	uint16_t  _reserved0;
	uint16_t  _reserved1;
} pkt_hdr_t;



// conf
uint16_t _conf_parse( saas_t *inst , const char *file );


// crypto
void pkt_encrypt( saas_t *inst , uint8_t *pkt , uint16_t *pkt_len );
uint16_t pkt_decrypt( saas_t *inst , uint8_t *pkt , uint16_t pkt_len );
void sha512( uint8_t *hash , const uint8_t *data , uint32_t data_len );
void sha512dual( uint8_t *hash , const uint8_t *data1 , uint32_t data1_len , const uint8_t *data2 , uint32_t data2_len );
void sha256( uint8_t *hash , const uint8_t *data , uint32_t data_len );
void sha256dual( uint8_t *hash , const uint8_t *data1 , uint32_t data1_len , const uint8_t *data2 , uint32_t data2_len );
uint16_t _conf_parse_enc_type( saas_t *inst , char *enc_type );


// log
void logh( saas_t *inst , uint8_t level , const saas_host_t *host , const char *pattern , ... );
void logc( saas_t *inst , uint8_t level , uint8_t ret , const char *pattern , ... );
void logm( saas_t *inst , uint8_t level , const char *pattern , ... );
void logd( saas_t *inst , uint8_t level , const void *data , uint32_t data_len );


// misc
uint32_t  gen_trans_id( void );
uint32_t  gen_rand( uint32_t max );
void  gen_rand_data( void *buf , uint32_t len );
void trim( char **str );
uint32_t u32tonet( uint32_t i );
uint32_t u32fromnet( uint32_t i );
uint16_t u16tonet( uint16_t i );
uint16_t u16fromnet( uint16_t i );


// net
uint16_t pkt_transceive( saas_t *inst , uint8_t *pkt , uint16_t *pkt_len , saas_host_t *host );
uint16_t is_ipv4( const char *ip );
uint16_t is_ipv6( const char *ip );
uint16_t copy_ipv4_addr( uint8_t *addr ,  const char *ip );
uint16_t copy_ipv6_addr( uint8_t *addr ,  const char *ip );


// host
void host_order( saas_t *inst );
saas_host_t *host_get_next( saas_t *inst );
void dump_hosts( saas_t *inst , uint8_t log_level , const char *line_prefix );



// pkt
void    pkt_req ( saas_t *saas , uint32_t *trans_id , uint8_t *pkt , uint16_t *pkt_len , uint32_t reqresp , uint16_t type , uint8_t *payload , uint16_t payload_len );
uint16_t pkt_resp( saas_t *saas , uint32_t  trans_id , uint8_t *pkt , uint16_t  pkt_len );

uint16_t pkt_req_authenticate       ( saas_t *saas , uint32_t *trans_id , uint8_t *pkt , uint16_t *pkt_len , const uint8_t *username  , const uint8_t *password );
uint16_t pkt_req_uid_to_username    ( saas_t *saas , uint32_t *trans_id , uint8_t *pkt , uint16_t *pkt_len , uint32_t uid );
uint16_t pkt_req_username_to_uid    ( saas_t *saas , uint32_t *trans_id , uint8_t *pkt , uint16_t *pkt_len , const uint8_t *username  , uint8_t username_len );
uint16_t pkt_req_gid_to_groupname   ( saas_t *saas , uint32_t *trans_id , uint8_t *pkt , uint16_t *pkt_len , uint32_t gid );
uint16_t pkt_req_groupname_to_gid   ( saas_t *saas , uint32_t *trans_id , uint8_t *pkt , uint16_t *pkt_len , const uint8_t *groupname , uint8_t groupname_len );
uint16_t pkt_req_user_info_by_uid     ( saas_t *saas , uint32_t *trans_id , uint8_t *pkt , uint16_t *pkt_len , uint32_t uid );
uint16_t pkt_req_user_info_by_username( saas_t *saas , uint32_t *trans_id , uint8_t *pkt , uint16_t *pkt_len , const uint8_t *username  , uint8_t username_len );
uint16_t pkt_req_user_info_with_groups_by_uid     ( saas_t *saas , uint32_t *trans_id , uint8_t *pkt , uint16_t *pkt_len , uint32_t uid );
uint16_t pkt_req_user_info_with_groups_by_username( saas_t *saas , uint32_t *trans_id , uint8_t *pkt , uint16_t *pkt_len , const uint8_t *username  , uint8_t username_len );
uint16_t pkt_req_user_info_with_all_groups_by_uid     ( saas_t *saas , uint32_t *trans_id , uint8_t *pkt , uint16_t *pkt_len , uint32_t uid );
uint16_t pkt_req_user_info_with_all_groups_by_username( saas_t *saas , uint32_t *trans_id , uint8_t *pkt , uint16_t *pkt_len , const uint8_t *username  , uint8_t username_len );
uint16_t pkt_req_group_info_by_gid      ( saas_t *saas , uint32_t *trans_id , uint8_t *pkt , uint16_t *pkt_len , uint32_t gid );
uint16_t pkt_req_group_info_by_groupname( saas_t *saas , uint32_t *trans_id , uint8_t *pkt , uint16_t *pkt_len , const uint8_t *groupname , uint8_t groupname_len );
uint16_t pkt_req_group_info_with_members_by_gid      ( saas_t *saas , uint32_t *trans_id , uint8_t *pkt , uint16_t *pkt_len , uint32_t gid );
uint16_t pkt_req_group_info_with_members_by_groupname( saas_t *saas , uint32_t *trans_id , uint8_t *pkt , uint16_t *pkt_len , const uint8_t *groupname , uint8_t groupname_len );
uint16_t pkt_req_group_info_with_all_members_by_gid      ( saas_t *saas , uint32_t *trans_id , uint8_t *pkt , uint16_t *pkt_len , uint32_t gid );
uint16_t pkt_req_group_info_with_all_members_by_groupname( saas_t *saas , uint32_t *trans_id , uint8_t *pkt , uint16_t *pkt_len , const uint8_t *groupname , uint8_t groupname_len );

uint16_t pkt_resp_authenticate    ( saas_t *saas , uint32_t trans_id , uint8_t *pkt , uint16_t pkt_len , uint32_t *pass_expire );
uint16_t pkt_resp_uid_to_username ( saas_t *saas , uint32_t trans_id , uint8_t *pkt , uint16_t pkt_len , uint8_t **username );
uint16_t pkt_resp_username_to_uid ( saas_t *saas , uint32_t trans_id , uint8_t *pkt , uint16_t pkt_len , uint32_t *uid );
uint16_t pkt_resp_gid_to_groupname( saas_t *saas , uint32_t trans_id , uint8_t *pkt , uint16_t pkt_len , uint8_t **groupname );
uint16_t pkt_resp_groupname_to_gid( saas_t *saas , uint32_t trans_id , uint8_t *pkt , uint16_t pkt_len , uint32_t *gid );
uint16_t pkt_resp_user_info       ( saas_t *saas , uint32_t trans_id , uint8_t *pkt , uint16_t pkt_len , saas_user_info_t  **user_info  );
uint16_t pkt_resp_group_info        ( saas_t *saas , uint32_t trans_id , uint8_t *pkt , uint16_t pkt_len , saas_group_info_t **group_info );





#endif // __H_a7dffdc5ac25a1a4ef41fecd853c6003_

